//
//  ViewConsProtocol.swift
//  CooperSwift_Example
//
//  Created by 计海峰 on 2021/10/14.
//  Copyright © 2021 CocoaPods. All rights reserved.
//

import Foundation
import SnapKit

// MARK: - 动态绑定key
private struct AssociateKeys {
    // 高度
    static var vHeightCons: Void?
    static var vMaxHeightCons: Void?
    static var vMinHeightCons: Void?
    
    // 宽度
    static var vWidthCons: Void?
    static var vMaxWidthCons: Void?
    static var vMinWidthCons: Void?
    
    // 其它约束
    static var vTopCons: Void?
    static var vLeftCons: Void?
    static var vBottomCons: Void?
    static var vRightCons: Void?
    
    static var vCenterXCons: Void?
    static var vCenterYCons: Void?
}

public enum ViewConsHeigh {
    case vHeightCons, vMaxHeightCons, vMinHeightCons,
         vWidthCons, vMaxWidthCons, vMinWidthCons,
         vTopCons, vLeftCons, vBottomCons, vRightCons,
         vCenterXCons, vCenterYCons
}

// MARK: - ViewConsProtocol 一些基本约束
public protocol ViewConsProtocol: AssociatedObjectStore { }
    
// MARK: - 外挂属性
public extension ViewConsProtocol {
    // 高度
    var vHeightCons: CGFloat { /// 高度
        get {
            return associatedObject(forKey: &AssociateKeys.vHeightCons, default: 0.0, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        set {
            setAssociatedObject(newValue, forKey: &AssociateKeys.vHeightCons, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    var vMaxHeightCons: CGFloat { /// 最大高度
        get {
            return associatedObject(forKey: &AssociateKeys.vMaxHeightCons, default: 0.0, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        set {
            setAssociatedObject(newValue, forKey: &AssociateKeys.vMaxHeightCons, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    var vMinHeightCons: CGFloat { /// 最小高度
        get {
            return associatedObject(forKey: &AssociateKeys.vMinHeightCons, default: 0.0, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        set {
            setAssociatedObject(newValue, forKey: &AssociateKeys.vMinHeightCons, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    // 宽度
    var vWidthCons: CGFloat { /// 宽度
        get {
            return associatedObject(forKey: &AssociateKeys.vWidthCons, default: 0.0, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        set {
            setAssociatedObject(newValue, forKey: &AssociateKeys.vWidthCons, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    var vMaxWidthCons: CGFloat { /// 最大宽度
        get {
            return associatedObject(forKey: &AssociateKeys.vMaxWidthCons, default: 0.0, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        set {
            setAssociatedObject(newValue, forKey: &AssociateKeys.vMaxWidthCons, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    var vMinWidthCons: CGFloat { /// 最小宽度
        get {
            return associatedObject(forKey: &AssociateKeys.vMinWidthCons, default: 0.0, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        set {
            setAssociatedObject(newValue, forKey: &AssociateKeys.vMinWidthCons, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }

    // 其它约束
    var vTopCons: CGFloat { /// 顶部
        get {
            return associatedObject(forKey: &AssociateKeys.vTopCons, default: 0.0, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        set {
            setAssociatedObject(newValue, forKey: &AssociateKeys.vTopCons, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    var vLeftCons: CGFloat { /// 左侧
        get {
            return associatedObject(forKey: &AssociateKeys.vLeftCons, default: 0.0, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        set {
            setAssociatedObject(newValue, forKey: &AssociateKeys.vLeftCons, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    var vBottomCons: CGFloat { /// 底部
        get {
            return associatedObject(forKey: &AssociateKeys.vBottomCons, default: 0.0, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        set {
            setAssociatedObject(newValue, forKey: &AssociateKeys.vBottomCons, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    var vRightCons: CGFloat { ///  右侧
        get {
            return associatedObject(forKey: &AssociateKeys.vRightCons, default: 0.0, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        set {
            setAssociatedObject(newValue, forKey: &AssociateKeys.vRightCons, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    
    // 中心约束
    var vCenterYCons: CGFloat { ///  y轴 中心对齐
        get {
            return associatedObject(forKey: &AssociateKeys.vCenterYCons, default: 0.0, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        set {
            setAssociatedObject(newValue, forKey: &AssociateKeys.vCenterYCons, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    var vCenterXCons: CGFloat { ///  x轴 中心对齐
        get {
            return associatedObject(forKey: &AssociateKeys.vCenterXCons, default: 0.0, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        set {
            setAssociatedObject(newValue, forKey: &AssociateKeys.vCenterXCons, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    
}

// MARK: - 正常基础约束
public extension ViewConsProtocol {
    
    func normalConsToSuperView(_ target: UIView, isRemake: Bool = true, highCons:[ViewConsHeigh]=[]) {
        guard let cons = target.superview else { return }
        normalConsTo(target, cons: cons, isRemake: isRemake, highCons: highCons)
    }
    
    /// 正常基础约束
    func normalConsTo(_ target: UIView, cons: UIView, isRemake: Bool = true, highCons:[ViewConsHeigh]=[]) {
        
        let makeBlock: (_ make: ConstraintMaker) -> Void =  { make in
            if self.vTopCons != 0 {
                if highCons.contains(.vTopCons) {
                    make.top.equalTo(cons).offset(self.vTopCons).priority(.high)
                }else {
                    make.top.equalTo(cons).offset(self.vTopCons)
                }
            }
            if self.vLeftCons != 0 {
                if highCons.contains(.vLeftCons) {
                    make.left.equalTo(cons).offset(self.vLeftCons).priority(.high)
                }else {
                    make.left.equalTo(cons).offset(self.vLeftCons)
                }
            }
            if self.vBottomCons != 0 {
                if highCons.contains(.vBottomCons) {
                    make.bottom.equalTo(cons).offset(self.vBottomCons).priority(.high)
                }else {
                    make.bottom.equalTo(cons).offset(self.vBottomCons)
                }
            }
            if self.vRightCons != 0 {
                if highCons.contains(.vRightCons) {
                    make.right.equalTo(cons).offset(self.vRightCons).priority(.high)
                }else {
                    make.right.equalTo(cons).offset(self.vRightCons)
                }
            }
            if self.vWidthCons > 0 {
                if highCons.contains(.vWidthCons) {
                    make.width.equalTo(self.vWidthCons).priority(.high)
                }else {
                    make.width.equalTo(self.vWidthCons)
                }
            }
            if self.vHeightCons > 0 {
                if highCons.contains(.vHeightCons) {
                    make.height.equalTo(self.vHeightCons).priority(.high)
                }else {
                    make.height.equalTo(self.vHeightCons)
                }
            }
        }
        
        if isRemake {
            target.snp.remakeConstraints(makeBlock)
        }else {
            target.snp.makeConstraints(makeBlock)
        }
        
    }
    
}
